package com.bitspilani.infonet.core;

import java.util.Timer;
import java.util.TimerTask;

import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;

import com.bitspilani.infonet.MainActivity;
import com.bitspilani.infonet.bo.LastKnownLocation;
import com.bitspilani.infonet.bo.PatchDetails;
import com.bitspilani.infonet.constants.GlobalConstants;
import com.bitspilani.infonet.serviceinterface.ServiceTask;
import com.google.gson.Gson;

public class GyroscopeHandler implements SensorEventListener{
	private Gson gson = new Gson();
	private static Timer gyroTimer= new Timer();
	private MainActivity mainActivity = new MainActivity();
	int  x=0, y=0, z=0; double r2d = 57.2957795 ; 
	int totalAngularMovement; double lowPassFactor = 0.7;
	double axisX, axisY, axisZ;
	int speed = 20;//default speed value
	int gyroTickCnt = 0;
	int max;
	String temp = "";
	float rating, avgSpeed=0;
	LastKnownLocation patchStartLocation, patchEndLocation;
	
	@Override
	public void onAccuracyChanged(Sensor arg0, int arg1) {
		// TODO Auto-generated method stub

	}
	
	@Override
	public void onSensorChanged(SensorEvent event) {
		axisX = event.values[0] * r2d;
		axisY = event.values[1] * r2d;
		axisZ = event.values[2] * r2d;

		//applying low pass filter
		x = (int)((x * lowPassFactor) + ((1-lowPassFactor)*axisX));
		y = (int)((y * lowPassFactor) + ((1-lowPassFactor)*axisY));
		z = (int)((z * lowPassFactor) + ((1-lowPassFactor)*axisZ));

		//removing minus sign
		x = x<0?(-1*x):x;
		y = y<0?(-1*y):y;
		z = z<0?(-1*z):z;

	/*	axisX =axisX<0?(-1*axisX):axisX;
		axisY = axisY<0?(-1*axisY):axisY;
		axisZ = axisZ<0?(-1*axisZ):axisZ;
		
		//removing minus sign
			double  totalRotation  = (axisX +axisY+axisZ);
	*/	
		totalAngularMovement += (x+y+z);//adding the average of angular velocities 
		//	totalAngularMovement = (int)((totalAngularMovement * lowPassFactor) + ((1-lowPassFactor)*totalRotation));

	}
	
	public void scheduleGyroTimer(){
		TimerTask task = new TimerTask() {

			@Override  
			public void run() {
				
				gyroTickCnt++;
			LastKnownLocation loc = LocationProvider.getBestKnownLocation();
				
				if(gyroTickCnt == 1){//first tick;
					patchStartLocation = loc;
				}
				System.out.println(gyroTickCnt+" "+totalAngularMovement);

				mainActivity.updateGyro("Rating "+rating, "gyroTickCnt: "+gyroTickCnt+"" +
						", totalAngularRotation: "+totalAngularMovement * GlobalConstants.SAMPLING_PERIOD);
				
				
				avgSpeed += loc.getSpeed();

				System.out.println("max: "+max);

				if(gyroTickCnt == GlobalConstants.SAMPLING_PERIOD){//process the data 
					patchEndLocation = loc;
					avgSpeed = (avgSpeed/GlobalConstants.SAMPLING_PERIOD)*(3.6f);//taking average and converting in kmph

					int totalAngularRotation = totalAngularMovement * GlobalConstants.SAMPLING_PERIOD;// (around total 6000 degree rotation will be there at the speed of 20 KM per hour on a very bad road)
					
					speed = (int) ((avgSpeed > 0)?avgSpeed:speed);//speed is either the avgspeed or setting it to a default speed for calculationß
					rating = (totalAngularRotation/speed)*GlobalConstants.ALPHA;
					if(rating > GlobalConstants.MAX_RATING){
						rating = GlobalConstants.MAX_RATING;
					}
					mainActivity.updateGyro("Rating "+rating, "gyroTickCnt: "+gyroTickCnt+"" +
							", totalAngularMovement: "+totalAngularMovement);

					
					String patchDetailJson = getPatchDetailJson (patchStartLocation, patchEndLocation, rating);
					System.out.println("patchDetailJson: "+patchDetailJson);
					
				     try {

				    	 new ServiceTask().execute(GlobalConstants.STORE_PATCH_DETAILS, patchDetailJson);
				        } catch (Exception e) {
				            e.printStackTrace();
				        }
					gyroTickCnt = 0;
					totalAngularMovement = 0;


				}
				
			}

			private String getPatchDetailJson(
					LastKnownLocation patchStartLocation,
					LastKnownLocation patchEndLocation, float rating) {
				PatchDetails patchDetail = new PatchDetails();
				
				patchDetail.setDeviceId(GlobalConstants.DEVICE_ID);
				patchDetail.setVehicleTypeId(GlobalConstants.VEHICLE_TYPE_ID);
				patchDetail.setPatchRating(rating);
				patchDetail.setPatchStartDetails(patchStartLocation);
				patchDetail.setPatchEndDetails(patchEndLocation);
				
				
				
				return gson.toJson(patchDetail);
			}  
		};  
		gyroTimer.scheduleAtFixedRate(task, 0, GlobalConstants.GYRO_TICK_FREQUENCY);  
	}


}
